home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / OLE2BOOK.ZIP / CHAP13.ZIP / PATRON / PAGE.CPP < prev    next >
C/C++ Source or Header  |  1993-06-27  |  32KB  |  1,315 lines

  1. /*
  2.  * PAGE.CPP
  3.  * Modifications for Chapter 13
  4.  *
  5.  * Implementation of parts of the CPage class; those member functions
  6.  * dealing with mouse events are in PAGEMOUS.CPP
  7.  *
  8.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  9.  *
  10.  * Kraig Brockschmidt, Software Design Engineer
  11.  * Microsoft Systems Developer Relations
  12.  *
  13.  * Internet  :  kraigb@microsoft.com
  14.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  15.  */
  16.  
  17.  
  18. #include "patron.h"
  19.  
  20.  
  21. /*
  22.  * CPage::CPage
  23.  * CPage::~CPage
  24.  *
  25.  * Constructor Parameters:
  26.  *  dwID            DWORD identifier for this page.
  27.  *  hWnd            HWND of the pages window (for repaints, etc).
  28.  *  pPG             LPCPages to the Pages window.
  29.  */
  30.  
  31. CPage::CPage(DWORD dwID, HWND hWnd, LPCPages pPG)
  32.     {
  33.     m_dwID     =dwID;
  34.     m_pIStorage=NULL;
  35.  
  36.     m_cOpens=0;
  37.     m_hWnd=hWnd;
  38.     m_pPG=pPG;
  39.  
  40.     m_dwIDNext      =0;
  41.     m_cTenants      =0;
  42.     m_hWndTenantList=NULL;
  43.     m_iTenantCur    =0xFFFF;    //Tenants are zero indexed.
  44.     m_pTenantCur    =NULL;
  45.  
  46.     m_uHTCode=HTNOWHERE;
  47.     m_uSizingFlags=0;
  48.     m_fTracking=FALSE;
  49.     m_hDC=NULL;
  50.  
  51.     //CHAPTER13MOD
  52.     m_pmkFile=NULL;
  53.     m_cRef=0L;
  54.     m_pIOleItemContainer=NULL;
  55.     //End CHAPTER13MOD
  56.  
  57.     return;
  58.     }
  59.  
  60.  
  61. CPage::~CPage(void)
  62.     {
  63.     m_hWnd=NULL;
  64.     Close(FALSE);
  65.     return;
  66.     }
  67.  
  68.  
  69.  
  70. //CHAPTER13MOD
  71. /*
  72.  * CPage::QueryInterface
  73.  * CPage::AddRef
  74.  * CPage::Release
  75.  *
  76.  * Purpose:
  77.  *  IUnknown members for CPage object.
  78.  */
  79.  
  80. STDMETHODIMP CPage::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  81.     {
  82.     *ppv=NULL;
  83.  
  84.     //Any interface on this object is the object pointer.
  85.     if (IsEqualIID(riid, IID_IUnknown))
  86.         *ppv=(LPVOID)this;
  87.  
  88.     if (IsEqualIID(riid, IID_IOleItemContainer)
  89.         || IsEqualIID(riid, IID_IOleContainer)
  90.         || IsEqualIID(riid, IID_IParseDisplayName))
  91.         *ppv=(LPVOID)m_pIOleItemContainer;
  92.  
  93.     if (NULL!=*ppv)
  94.         {
  95.         ((LPUNKNOWN)*ppv)->AddRef();
  96.         return NOERROR;
  97.         }
  98.  
  99.     return ResultFromScode(E_NOINTERFACE);
  100.     }
  101.  
  102.  
  103. STDMETHODIMP_(ULONG) CPage::AddRef(void)
  104.     {
  105.     return ++m_cRef;
  106.     }
  107.  
  108. STDMETHODIMP_(ULONG) CPage::Release(void)
  109.     {
  110.     ULONG           cRefT;
  111.  
  112.     cRefT=--m_cRef;
  113.  
  114.     if (0L==m_cRef)
  115.         delete this;
  116.  
  117.     return cRefT;
  118.     }
  119.  
  120. //End CHAPTER13MOD
  121.  
  122.  
  123.  
  124.  
  125. /*
  126.  * CPage::GetID
  127.  *
  128.  * Return Value:
  129.  *  DWORD           dwID field in this page.  This function is only here
  130.  *                  to avoid hiding inline implementations in pages.h
  131.  */
  132.  
  133. DWORD CPage::GetID(void)
  134.     {
  135.     return m_dwID;
  136.     }
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143. /*
  144.  * CPage::FOpen
  145.  *
  146.  * Purpose:
  147.  *  Retrieves the IStorage associated with this page.  The IStorage is
  148.  *  owned by the page and thus the page always holds a reference count.
  149.  *  The caller should call ::Close or delete this page to match this open.
  150.  *
  151.  *  This function may be called multiple times resulting in additional
  152.  *  reference counts on the storage each of which must be matched with
  153.  *  a call to ::Close.  The last ::Close can be done through delete.
  154.  *
  155.  * Parameters:
  156.  *  pIStorage       LPSTORAGE in which this page lives.
  157.  *
  158.  * Return Value:
  159.  *  BOOL            TRUE if opening succeeds, FALSE otherwise.
  160.  */
  161.  
  162. BOOL CPage::FOpen(LPSTORAGE pIStorage)
  163.     {
  164.     HRESULT                 hr=NOERROR;
  165.     LPSTREAM                pIStream;
  166.     DWORD                   dwMode;
  167.     char                    szTemp[32];
  168.     BOOL                    fNew;
  169.     BOOL                    fCreated=FALSE;
  170.     TENANTLIST              tl;
  171.     LPTENANTINFO            pti;
  172.     ULONG                   cb;
  173.     LPMALLOC                pIMalloc;
  174.     UINT                    i;
  175.     LPTENANT                pTenant;
  176.     UINT                    cLinks;
  177.     LPOLELINK               pIOleLink;
  178.     LPUNKNOWN               pIUnknown;
  179.     UINT                    uRet;
  180.     OLEUIEDITLINKS          el;
  181.     LPCIOleUILinkContainer  pIUILinks;
  182.     HWND                    hWndDoc;
  183.  
  184.     fNew=(NULL==m_pIStorage);
  185.  
  186.     if (!fNew)
  187.         {
  188.         m_cOpens++;
  189.         m_pIStorage->AddRef();
  190.         return TRUE;
  191.         }
  192.  
  193.     if (NULL==pIStorage)
  194.         return FALSE;
  195.  
  196.     /*
  197.      * Attempt to open the storage under this ID.  If there is none, then
  198.      * create it.  In either case we end up with an IStorage that we
  199.      * either save in pPage or release.
  200.      */
  201.  
  202.     GetStorageName(szTemp);
  203.     dwMode=STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
  204.  
  205.     hr=pIStorage->OpenStorage(szTemp, NULL, dwMode, NULL, 0, &m_pIStorage);
  206.  
  207.     if (FAILED(hr))
  208.         {
  209.         hr=pIStorage->CreateStorage(szTemp, dwMode, 0, 0, &m_pIStorage);
  210.         fCreated=TRUE;
  211.         }
  212.  
  213.     if (FAILED(hr))
  214.         return FALSE;
  215.  
  216.     m_cOpens++;
  217.  
  218.     if (NULL==m_hWndTenantList)
  219.         {
  220.         /*
  221.          * The first time we open this page, create the hidden listbox
  222.          * we'll use to track tenants.  We give it the owner-draw style
  223.          * so we can just store pointers in it.
  224.          */
  225.         m_hWndTenantList=CreateWindow("listbox", "Tenant List"
  226.             , WS_POPUP | LBS_OWNERDRAWFIXED, 0, 0, 100, 100
  227.             , HWND_DESKTOP, NULL, m_pPG->m_hInst, NULL);
  228.  
  229.         if (NULL==m_hWndTenantList)
  230.             return FALSE;
  231.         }
  232.  
  233.     //CHAPTER13MOD
  234.     m_pIOleItemContainer=new CImpIOleItemContainer((LPVOID)this
  235.         , (LPUNKNOWN)this, FALSE);
  236.  
  237.     if (NULL==m_pIOleItemContainer)
  238.         return FALSE;
  239.     //End CHAPTER13MOD
  240.  
  241.     //If this is brand-new, we're done.
  242.     if (fCreated)
  243.         return TRUE;
  244.  
  245.  
  246.     /*
  247.      * Now open the stream we saved in ::Close and load all the
  248.      * tenants listed in there.  If there are none, then we don't
  249.      * have to load squat.
  250.      */
  251.  
  252.     hr=m_pIStorage->OpenStream(SZSTREAMTENANTLIST, NULL, STGM_DIRECT
  253.         | STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pIStream);
  254.  
  255.     if (FAILED(hr))
  256.         return FALSE;
  257.  
  258.     if (SUCCEEDED(CoGetMalloc(MEMCTX_SHARED, &pIMalloc)))
  259.         {
  260.         pIStream->Read((LPVOID)&tl, sizeof(tl), NULL);
  261.         m_cTenants=tl.cTenants;
  262.         m_dwIDNext=tl.dwIDNext;
  263.         m_iTenantCur=0;
  264.  
  265.         cb=tl.cTenants*sizeof(TENANTINFO);
  266.  
  267.         if (0!=cb)
  268.             {
  269.             pti=(LPTENANTINFO)pIMalloc->Alloc(cb);
  270.  
  271.             if (NULL!=pti)
  272.                 {
  273.                 pIStream->Read((LPVOID)pti, cb, NULL);
  274.  
  275.                 for (i=0; i < m_cTenants; i++)
  276.                     {
  277.                     if (FTenantAdd(-1, (pti+i)->dwID, &pTenant))
  278.                         {
  279.                         pTenant->FLoad(m_pIStorage, &(pti+i)->fe, &(pti+i)->rcl);
  280.                         pTenant->ShowObjectType(m_pPG->m_fShowTypes);
  281.                         }
  282.                     }
  283.  
  284.                 pIMalloc->Free((LPVOID)pti);
  285.                 }
  286.             }
  287.  
  288.         pIMalloc->Release();
  289.         }
  290.  
  291.     pIStream->Release();
  292.  
  293.     //Get and select the first tenant
  294.     if (FTenantGet(0, &m_pTenantCur, FALSE))
  295.         m_pTenantCur->Select(TRUE);
  296.  
  297.  
  298.     /*
  299.      * Update all the links in this page, showing the progress indicator
  300.      * as it's happening.  We use the same IOlUILinkContainer
  301.      * implementation as we do for the links dialog, passing it to
  302.      * OleUIUpdateLinks which does everything for us.
  303.      *
  304.      * We might also optimize this to not do anything if there are no
  305.      * automatic links, but it's not a big concern.
  306.      */
  307.  
  308.     //First, count the number of automatic links.
  309.     cLinks=0;
  310.  
  311.     for (i=0; i < m_cTenants; i++)
  312.         {
  313.         if (FTenantGet(i, &pTenant, FALSE))
  314.             {
  315.             DWORD       dw;
  316.  
  317.             pTenant->ObjectGet(&pIUnknown);
  318.             hr=pIUnknown->QueryInterface(IID_IOleLink, (LPLPVOID)&pIOleLink);
  319.             pIUnknown->Release();
  320.  
  321.             if (FAILED(hr))
  322.                 continue;
  323.  
  324.             pIOleLink->GetUpdateOptions(&dw);
  325.             pIOleLink->Release();
  326.  
  327.             if (OLEUPDATE_ALWAYS==dw)
  328.                 cLinks++;
  329.             }
  330.         }
  331.  
  332.     //If we have any automatic links, invoke the update